#include "rectangle.h"
#include <QPainter>
#include <QLineF>

Rectangle::Rectangle(const QPointF &startPoint, const QPointF &endPoint, const QColor &color)
    : MyShape(startPoint, color), endPoint_(endPoint) {}

QRectF Rectangle::boundingRect() const
{
    QRectF r = rect();
    return QRectF(r.topLeft() - QPointF(hitRadius_ + penWidth_, hitRadius_ + penWidth_),
                  r.bottomRight() + QPointF(hitRadius_ + penWidth_, hitRadius_ + penWidth_));
}

void Rectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);

    QRectF r = rect();
    painter->setPen(QPen(color_, penWidth_));
    painter->setBrush(QBrush(Qt::transparent));
    painter->drawRect(r);

    if (isSelected_ || tlHighlighted_ || trHighlighted_ || blHighlighted_ || brHighlighted_ || edgeHighlighted_) {
        painter->setPen(QPen(Qt::blue, penWidth_));
        painter->setBrush(QBrush(Qt::blue));

        if (tlHighlighted_ || isSelected_) {
            painter->drawEllipse(r.topLeft(), hitRadius_/2, hitRadius_/2);
        }
        if (trHighlighted_ || isSelected_) {
            painter->drawEllipse(r.topRight(), hitRadius_/2, hitRadius_/2);
        }
        if (blHighlighted_ || isSelected_) {
            painter->drawEllipse(r.bottomLeft(), hitRadius_/2, hitRadius_/2);
        }
        if (brHighlighted_ || isSelected_) {
            painter->drawEllipse(r.bottomRight(), hitRadius_/2, hitRadius_/2);
        }
    }
}

bool Rectangle::isPointNear(const QPointF &point) const
{
    QRectF r = rect();

    // Check corners
    if (QLineF(r.topLeft(), point).length() <= hitRadius_ ||
        QLineF(r.topRight(), point).length() <= hitRadius_ ||
        QLineF(r.bottomLeft(), point).length() <= hitRadius_ ||
        QLineF(r.bottomRight(), point).length() <= hitRadius_) {
        return true;
    }

    // Check edges
    return isPointNearEdge(point, r);
}

void Rectangle::highlightControlPoints(const QPointF &point)
{
    QRectF r = rect();
    tlHighlighted_ = QLineF(r.topLeft(), point).length() <= hitRadius_;
    trHighlighted_ = QLineF(r.topRight(), point).length() <= hitRadius_;
    blHighlighted_ = QLineF(r.bottomLeft(), point).length() <= hitRadius_;
    brHighlighted_ = QLineF(r.bottomRight(), point).length() <= hitRadius_;
    edgeHighlighted_ = isPointNearEdge(point, r);
}

QRectF Rectangle::rect() const
{
    return QRectF(startPoint_, endPoint_).normalized();
}

bool Rectangle::isPointNearEdge(const QPointF &point, const QRectF &rect) const
{
    QLineF edges[4] = {
        QLineF(rect.topLeft(), rect.topRight()),
        QLineF(rect.topRight(), rect.bottomRight()),
        QLineF(rect.bottomRight(), rect.bottomLeft()),
        QLineF(rect.bottomLeft(), rect.topLeft())
    };

    for (const QLineF& edge : edges) {
        if (edge.length() < 1e-6) continue;

        qreal t = QPointF::dotProduct(point - edge.p1(), edge.p2() - edge.p1()) /
                  (edge.length() * edge.length());
        if (t >= 0 && t <= 1) {
            QPointF projection = edge.p1() + t * (edge.p2() - edge.p1());
            if (QLineF(point, projection).length() <= hitRadius_) {
                return true;
            }
        }
    }
    return false;
}
